﻿using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.BusinessEntity.YunZhiJia;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using LiMinCRMPlugin.InterfaceDocking;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;

namespace LiMinCRMPlugin
{
    /// <summary>
    /// 销售普通发票执行计划插件
    /// </summary>
    /// <remarks>
    /// 功能：执行计划遍历销售普通发票更新发票号等信息到CRM。
    /// 创建人：wzx
    /// 创建日期：2024.4.3
    /// 修改信息（1）：修改人，修改日期，修改内容
    /// </remarks>
    [Description("销售普通发票更新CRM执行计划")]
    [HotUpdate]
    public class SalesOrdinaryInvoiceUpdateCRM : IScheduleService
    {

        public void Run(Context ctx, Schedule schedule)
        {


            #region 更新本地应收单
            var sql1 = @"/*dialect*/select DISTINCT a.FID,FINVOICENO,FIVNUMBER,d.FSBILLID  from T_IV_SALESIC a
            inner join T_IV_SALESIC_O b on a.FID=b.FID
            inner join T_IV_SALESICENTRY c on a.FID=c.FID
            inner join T_IV_SALESICENTRY_LK d on c.FENTRYID=d.FENTRYID and  FRULEID='IV_ReceivableToSalesOC_Entry'
            inner join t_AR_receivable aa on aa.FID=d.FSBILLID
            where FFORMID='IV_SALESOC' and a.FDOCUMENTSTATUS='C' and F_QLTK_fphm=''  and F_QLTK_Synchronous<>'1'  and (FINVOICENO<>'' or FIVNUMBER<>'')";

            DataTable dt_SK1 = DBUtils.ExecuteDataSet(ctx, sql1).Tables[0];

            foreach (DataRow reader in dt_SK1.Rows)
            {

                string INVOICENO = Convert.ToString(reader["FINVOICENO"]);//发票号
                string IVNUMBER = Convert.ToString(reader["FIVNUMBER"]);//发票号

                string FSBILLID = Convert.ToString(reader["FSBILLID"]);//应收单内码
                string FID = Convert.ToString(reader["FID"]);

                string FPH = "";
                if (!IVNUMBER.IsNullOrEmptyOrWhiteSpace())
                {
                    FPH = IVNUMBER;
                }
                else
                {
                    FPH = INVOICENO;
                }

                //更新应收单发票号码
                string SQLYSD = string.Format(@"/*dialect*/update t_AR_receivable set F_QLTK_fphm ='{0}' where FID='{1}' and (F_QLTK_fphm='' or F_QLTK_fphm=' ' or F_QLTK_fphm is  null) ", FPH, FSBILLID);
                DBUtils.ExecuteDataSet(ctx, SQLYSD);

                string sqlfp = string.Format(@"/*dialect*/update T_IV_SALESIC set F_QLTK_Synchronous ='1' where FID='{0}'", FID);
                DBUtils.ExecuteDataSet(ctx, sqlfp);

            }
            #endregion

            //throw new NotImplementedException();
            #region 销售普通发票
            var sql = @"/*dialect*/select FBILLNO,a.FID,FPDFURLCOPY,F_DEV_CRMNumber,FINVOICENO,FIVNUMBER,FCREATORID,d.FSBILLID,F_DEV_CRMId from T_IV_SALESIC a
inner join T_IV_SALESIC_O b on a.FID=b.FID
inner join T_IV_SALESICENTRY c on a.FID=c.FID
inner join T_IV_SALESICENTRY_LK d on c.FENTRYID=d.FENTRYID and  FRULEID='IV_ReceivableToSalesOC_Entry'
where FFORMID='IV_SALESOC' and FDOCUMENTSTATUS='C' and F_DEV_CRMId <> '' and F_DEV_CRMId is not null and F_RDLV_FSTATUS<>'成功' and (FINVOICENO<>'' or FIVNUMBER<>'')";
            DataTable dt_SK = DBUtils.ExecuteDataSet(ctx, sql).Tables[0];
            List<SalesOrdinaryInvoiceModel.detailList> detailList = new List<SalesOrdinaryInvoiceModel.detailList>();//明细数据组
            foreach (DataRow reader in dt_SK.Rows)
            {
                string FID = Convert.ToString(reader["FID"]);
                string FBILLNO = Convert.ToString(reader["FBILLNO"]);
                string PDFURLCOPY = Convert.ToString(reader["FPDFURLCOPY"]);//电子发票地址
                string CRMNumber = Convert.ToString(reader["F_DEV_CRMNumber"]);//CRM编码
                string INVOICENO = Convert.ToString(reader["FINVOICENO"]);//发票号
                string IVNUMBER = Convert.ToString(reader["FIVNUMBER"]);//发票号
                string UserID = Convert.ToString(reader["FCREATORID"]);//用户ID
                string UserAccount = "";//用户账号
                string FSBILLID= Convert.ToString(reader["FSBILLID"]);//应收单内码
                string CRMId= Convert.ToString(reader["F_DEV_CRMId"]);//CRMID


                string SQLUser = string.Format(@"/*dialect*/select FUSERACCOUNT from T_SEC_user where FUSERID='{0}' ", UserID);
                DataTable dtUser = DBUtils.ExecuteDataSet(ctx, SQLUser).Tables[0];
                if (dtUser.Rows.Count > 0)
                {
                    UserAccount = dtUser.Rows[0]["FUSERACCOUNT"].ToString();
                }
                string FPH = "";
                if (!IVNUMBER.IsNullOrEmptyOrWhiteSpace())
                {
                    FPH = IVNUMBER;
                }
                else
                {
                    FPH = INVOICENO;
                }

                //更新应收单发票号码
                string SQLYSD = string.Format(@"/*dialect*/update t_AR_receivable set F_QLTK_fphm ='{0}' where FID='{1}' and (F_QLTK_fphm='' or F_QLTK_fphm=' ' or F_QLTK_fphm is  null) ", FPH, FSBILLID);
                DBUtils.ExecuteDataSet(ctx, SQLYSD);

                #region 销售普通发票detail数组
                SalesOrdinaryInvoiceModel.operate operate = new SalesOrdinaryInvoiceModel.operate();
                operate.action = "SaveOrUpdate";

                SalesOrdinaryInvoiceModel.dataList dataList = new SalesOrdinaryInvoiceModel.dataList();
                SalesOrdinaryInvoiceModel.detailList detailList1 = new SalesOrdinaryInvoiceModel.detailList();
                detailList1.operate = operate;
                detailList1.data = dataList;
                detailList.Add(detailList1);
                #endregion
                #region 构建请求body报文
                SalesOrdinaryInvoiceModel.mainTableList mainTable = new SalesOrdinaryInvoiceModel.mainTableList
                {

                    crmbm = CRMNumber,//CRM编码
                    kpjl = PDFURLCOPY,//电子发票地址
                    fphm = FPH//发票号                 
                };
                #endregion
                //非CRM生成发票不同步更新CRM
                if (!CRMId.IsNullOrEmptyOrWhiteSpace())
                {
                    Return resultAdd = CRMUpdateSalesOrdinaryInvoice(ctx, mainTable, detailList, UserAccount);
                    if (resultAdd.status == "1")
                    {
                        #region 销售普通发票写日志(插入一张CRM接口日志单据，更新单据上的接口调用方式/调用时间/调用结果）
                        Common.InterfaceLog interfaceLog = new Common.InterfaceLog();
                        interfaceLog.FBILLNO = FBILLNO;
                        interfaceLog.FBILLID = FID;
                        interfaceLog.FDATE = System.DateTime.Now;
                        interfaceLog.FINTERNAME = "新增销售普通发票";
                        interfaceLog.FInvokeType = "";
                        interfaceLog.Ftoken = "";
                        interfaceLog.FSTATUS = "成功";
                        interfaceLog.FRequsetData = "{\"data\":[{\"operationinfo\":{\"operator\":\"" + UserAccount + "\",\"operationDate\":\"" + DateTime.Now.ToString("yyyy-MM-dd") + "\",\"operationTime\":\"" + DateTime.Now.ToString("HH:mm:ss") + "\"},\"mainTable\":" + JsonConvert.SerializeObject(mainTable) + "}],\"header\":{\"systemid\":\"kingde\",\"" + DateTime.Now + "\":\"currentTimeTamp \",\"Md5\":\"\"}}";
                        interfaceLog.FReturnData = JsonConvert.SerializeObject(resultAdd.datajson);
                        interfaceLog.FRequest = "{\"data\":[{\"operationinfo\":{\"operator\":\"" + UserAccount + "\",\"operationDate\":\"" + DateTime.Now.ToString("yyyy-MM-dd") + "\",\"operationTime\":\"" + DateTime.Now.ToString("HH:mm:ss") + "\"},\"mainTable\":" + JsonConvert.SerializeObject(mainTable) + "}],\"header\":{\"systemid\":\"kingde\",\"" + DateTime.Now + "\":\"currentTimeTamp \",\"Md5\":\"\"}}";
                        interfaceLog.FReturn = JsonConvert.SerializeObject(resultAdd.datajson);
                        string LogSql = interfaceLog.WriteCRMLogSql();//获取写入日志单据的SQL
                        List<string> sqlList = new List<string>();
                        if (!string.IsNullOrEmpty(LogSql))
                        {
                            sqlList.Add(LogSql);
                        }
                        //更新单据
                        string updateSql = string.Format(@"/*dialect*/ update T_IV_SALESIC set F_RDLV_FSTATUS='成功' ,F_RDLV_FDATE='{0}'
                    where FID='{1}'", interfaceLog.FDATE, FID);
                        sqlList.Add(updateSql);
                        DBServiceHelper.ExecuteBatch(ctx, sqlList);
                        #endregion
                    }
                    else
                    {
                        #region 销售普通发票写日志(插入一张CRM接口日志单据，更新单据上的接口调用方式/调用时间/调用结果）
                        Common.InterfaceLog interfaceLog = new Common.InterfaceLog();
                        interfaceLog.FBILLNO = FBILLNO;
                        interfaceLog.FBILLID = FID;
                        interfaceLog.FDATE = System.DateTime.Now;
                        interfaceLog.FINTERNAME = "新增销售普通发票";
                        interfaceLog.FInvokeType = "";
                        interfaceLog.Ftoken = "";
                        interfaceLog.FSTATUS = "失败";
                        interfaceLog.FRequsetData = "{\"data\":[{\"operationinfo\":{\"operator\":\"" + UserAccount + "\",\"operationDate\":\"" + DateTime.Now.ToString("yyyy-MM-dd") + "\",\"operationTime\":\"" + DateTime.Now.ToString("HH:mm:ss") + "\"},\"mainTable\":" + JsonConvert.SerializeObject(mainTable) + "}],\"header\":{\"systemid\":\"kingde\",\"" + DateTime.Now + "\":\"currentTimeTamp \",\"Md5\":\"\"}}";
                        interfaceLog.FReturnData = JsonConvert.SerializeObject(resultAdd.datajson);
                        interfaceLog.FRequest = "{\"data\":[{\"operationinfo\":{\"operator\":\"" + UserAccount + "\",\"operationDate\":\"" + DateTime.Now.ToString("yyyy-MM-dd") + "\",\"operationTime\":\"" + DateTime.Now.ToString("HH:mm:ss") + "\"},\"mainTable\":" + JsonConvert.SerializeObject(mainTable) + "}],\"header\":{\"systemid\":\"kingde\",\"" + DateTime.Now + "\":\"currentTimeTamp \",\"Md5\":\"\"}}";
                        interfaceLog.FReturn = JsonConvert.SerializeObject(resultAdd.datajson);
                        string LogSql = interfaceLog.WriteCRMLogSql();//获取写入日志单据的SQL
                        List<string> sqlList = new List<string>();
                        if (!string.IsNullOrEmpty(LogSql))
                        {
                            sqlList.Add(LogSql);
                        }
                        //更新单据
                        string updateSql = string.Format(@"/*dialect*/ update T_IV_SALESIC set F_RDLV_FSTATUS='失败' ,F_RDLV_FDATE='{0}'
                    where FID='{1}'", interfaceLog.FDATE, FID);
                        sqlList.Add(updateSql);
                        DBServiceHelper.ExecuteBatch(ctx, sqlList);
                        #endregion
                    }
                }
                
            }


            #endregion

            
        }


        /// <summary>
        /// api配置
        /// </summary>
        public DataTable APISetting(Context ctx, string InterfaceName)
        {
            string Sql = string.Format(@"select * from RDLV_t_CRMInterface where F_RDLV_InterfaceName='{0}'", InterfaceName);
            return DBServiceHelper.ExecuteDataSet(ctx, Sql).Tables[0];
        }



        /// <summary>
        /// CRM更新销售普通发票接口
        /// </summary>
        public Return CRMUpdateSalesOrdinaryInvoice(Context ctx,SalesOrdinaryInvoiceModel.mainTableList mainTable, List<SalesOrdinaryInvoiceModel.detailList> detail1, string UserAccount)
        {
            //当前日期
            String currentDate = DateTime.Now.ToString("yyyy-MM-dd");
            //当前时间
            String currentTime = DateTime.Now.ToString("hh:mm:ss");

            string requestUri1 = "http://10.10.17.127:8086/api/cube/restful/interface/saveOrUpdateModeData/update_invoice_feedback";

            //系统标识
            String systemid = "kingdee";
            //密码
            String d_password = "p@ssw0rd...";
            DataTable dt = APISetting(ctx,"更新销售发票");
            if (dt.Rows.Count > 0)
            {
                requestUri1 = Convert.ToString(dt.Rows[0]["F_RDLV_URL"]);
                systemid = Convert.ToString(dt.Rows[0]["F_RDLV_SystemId"]);
                d_password = Convert.ToString(dt.Rows[0]["F_RDLV_Password"]);
            }
            //获取时间戳
            String currentTimeTamp = getTimestamp();
            String md5Source = systemid + d_password + currentTimeTamp;
            String md5OfStr = Md5(md5Source).ToLower();

            Return result = PostToUpdateNews(requestUri1, systemid, currentTimeTamp, md5OfStr, mainTable, detail1,UserAccount);


            return result;
        }



        /// <summary>
        /// md5加密
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static String Md5(string s)
        {
            char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(s);
            byte[] result = md5.ComputeHash(inputBytes);
            int j = result.Length;
            char[] str = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++)
            {
                byte byte0 = result[i];
                str[k++] = hexDigits[byte0 >> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        }






        /// <summary>
        /// CRM更新销售普通发票POST
        /// </summary>
        public static Return PostToUpdateNews(string url, string systemid, string currentTimeTamp, string md5OfStr, SalesOrdinaryInvoiceModel.mainTableList mainTable, List<SalesOrdinaryInvoiceModel.detailList> detail1, string UserAccount)
        {

            Dictionary<string, string> dic = new Dictionary<string, string>
            {
                {"datajson","{\"data\":[{\"operationinfo\":{\"operator\":\"CRM\",\"operationDate\":\""+DateTime.Now.ToString("yyyy-MM-dd")+"\",\"operationTime\":\""+DateTime.Now.ToString("HH:mm:ss")+"\"},\"mainTable\":"+JsonConvert.SerializeObject(mainTable)+",\"detail1\":"+JsonConvert.SerializeObject(detail1)+"}],\"header\":{\"systemid\":\""+systemid+"\",\"currentDateTime\":\""+currentTimeTamp+"\",\"Md5\":\""+md5OfStr+"\"}}"}
            };
            string result = string.Empty;
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
            #region 添加Post 参数
            StringBuilder builder = new StringBuilder();
            int i = 0;
            foreach (var item in dic)
            {
                if (i > 0)
                    builder.Append("&");
                builder.AppendFormat("{0}={1}", item.Key, item.Value);
                i++;
            }
            string b = builder.ToString();
            byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
            req.ContentLength = data.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            #endregion

            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            Return @return = new Return();
            result = Regex.Unescape(result);//去除转义符
            result = Regex.Unescape(result);//去除转义符
            string[] resAry = result.Split(new string[] { "status" }, StringSplitOptions.None);
            string[] json = result.Split(new string[] { "datajson" }, StringSplitOptions.None);
            string status = "";
            status = resAry[resAry.Length - 1].Replace("\"", "");
            status = status.Replace(":", "");
            status = status.Replace("}", "");
            string json1 = json[json.Length - 1].Remove(0, 3);
            json1 = Regex.Replace(json1, "\"\"", "\"");
            json1 = Regex.Unescape(json1);
            //}
            @return.status = status;
            @return.datajson = json1;
            return @return;
        }


        /**
       * 获取时间戳   格式如：19990101235959
       * @return
       */
        public static String getTimestamp()
        {

            return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").Replace("-", "").Replace(":", "").Replace(" ", "").Replace("/", "");
        }


        /**
       * 接口返回值自定义 
       */
        public class Return
        {
            public string status { get; set; }
            public string datajson { get; set; }
        }
    }
}

